home *** CD-ROM | disk | FTP | other *** search
/ Freelog 125 / Freelog_MarsAvril2015_No125.iso / ViePratique / ArchiFacile / ArchiFacileSetup.exe / {app} / nw.pak / Unnamed File 000130.txt < prev    next >
Text File  |  2014-10-14  |  7KB  |  280 lines

  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4.  
  5. cr.define('cr.ui', function() {
  6.  
  7.   /** @const */ var MenuItem = cr.ui.MenuItem;
  8.  
  9.   /**
  10.    * Creates a new menu element. Menu dispatches all commands on the element it
  11.    * was shown for.
  12.    *
  13.    * @param {Object=} opt_propertyBag Optional properties.
  14.    * @constructor
  15.    * @extends {HTMLMenuElement}
  16.    */
  17.   var Menu = cr.ui.define('menu');
  18.  
  19.   Menu.prototype = {
  20.     __proto__: HTMLMenuElement.prototype,
  21.  
  22.     selectedIndex_: -1,
  23.  
  24.     /**
  25.      * Element for which menu is being shown.
  26.      */
  27.     contextElement: null,
  28.  
  29.     /**
  30.      * Selector for children which are menu items.
  31.      */
  32.     menuItemSelector: '*',
  33.  
  34.     /**
  35.      * Initializes the menu element.
  36.      */
  37.     decorate: function() {
  38.       this.addEventListener('mouseover', this.handleMouseOver_);
  39.       this.addEventListener('mouseout', this.handleMouseOut_);
  40.  
  41.       this.classList.add('decorated');
  42.       this.setAttribute('role', 'menu');
  43.       this.hidden = true;  // Hide the menu by default.
  44.  
  45.       // Decorate the children as menu items.
  46.       var menuItems = this.menuItems;
  47.       for (var i = 0, menuItem; menuItem = menuItems[i]; i++) {
  48.         cr.ui.decorate(menuItem, MenuItem);
  49.       }
  50.     },
  51.  
  52.     /**
  53.      * Adds menu item at the end of the list.
  54.      * @param {Object} item Menu item properties.
  55.      * @return {cr.ui.MenuItem} The created menu item.
  56.      */
  57.     addMenuItem: function(item) {
  58.       var menuItem = this.ownerDocument.createElement('menuitem');
  59.       this.appendChild(menuItem);
  60.  
  61.       cr.ui.decorate(menuItem, MenuItem);
  62.  
  63.       if (item.label)
  64.         menuItem.label = item.label;
  65.  
  66.       if (item.iconUrl)
  67.         menuItem.iconUrl = item.iconUrl;
  68.  
  69.       return menuItem;
  70.     },
  71.  
  72.     /**
  73.      * Adds separator at the end of the list.
  74.      */
  75.     addSeparator: function() {
  76.       var separator = this.ownerDocument.createElement('hr');
  77.       cr.ui.decorate(separator, MenuItem);
  78.       this.appendChild(separator);
  79.     },
  80.  
  81.     /**
  82.      * Clears menu.
  83.      */
  84.     clear: function() {
  85.       this.textContent = '';
  86.     },
  87.  
  88.     /**
  89.      * Walks up the ancestors of |el| until a menu item belonging to this menu
  90.      * is found.
  91.      * @param {Element} el The element to start searching from.
  92.      * @return {cr.ui.MenuItem} The found menu item or null.
  93.      * @private
  94.      */
  95.     findMenuItem_: function(el) {
  96.       while (el && el.parentNode != this) {
  97.         el = el.parentNode;
  98.       }
  99.       return el;
  100.     },
  101.  
  102.     /**
  103.      * Handles mouseover events and selects the hovered item.
  104.      * @param {Event} e The mouseover event.
  105.      * @private
  106.      */
  107.     handleMouseOver_: function(e) {
  108.       var overItem = this.findMenuItem_(e.target);
  109.       this.selectedItem = overItem;
  110.     },
  111.  
  112.     /**
  113.      * Handles mouseout events and deselects any selected item.
  114.      * @param {Event} e The mouseout event.
  115.      * @private
  116.      */
  117.     handleMouseOut_: function(e) {
  118.       this.selectedItem = null;
  119.     },
  120.  
  121.     get menuItems() {
  122.       return this.querySelectorAll(this.menuItemSelector);
  123.     },
  124.  
  125.     /**
  126.      * The selected menu item or null if none.
  127.      * @type {cr.ui.MenuItem}
  128.      */
  129.     get selectedItem() {
  130.       return this.menuItems[this.selectedIndex];
  131.     },
  132.     set selectedItem(item) {
  133.       var index = Array.prototype.indexOf.call(this.menuItems, item);
  134.       this.selectedIndex = index;
  135.     },
  136.  
  137.     /**
  138.      * Focuses the selected item. If selectedIndex is invalid, set it to 0
  139.      * first.
  140.      */
  141.     focusSelectedItem: function() {
  142.       if (this.selectedIndex < 0 ||
  143.           this.selectedIndex > this.menuItems.length) {
  144.         this.selectedIndex = 0;
  145.       }
  146.  
  147.       if (this.selectedItem) {
  148.         this.selectedItem.focus();
  149.         this.setAttribute('aria-activedescendant', this.selectedItem.id);
  150.       }
  151.     },
  152.  
  153.     /**
  154.      * Menu length
  155.      */
  156.     get length() {
  157.       return this.menuItems.length;
  158.     },
  159.  
  160.     /**
  161.      * Returns if the menu has any visible item.
  162.      * @return {boolean} True if the menu has visible item. Otherwise, false.
  163.      */
  164.     hasVisibleItems: function() {
  165.       var menuItems = this.menuItems;  // Cache.
  166.       for (var i = 0, menuItem; menuItem = menuItems[i]; i++) {
  167.         if (!menuItem.hidden)
  168.           return true;
  169.       }
  170.       return false;
  171.     },
  172.  
  173.     /**
  174.      * This is the function that handles keyboard navigation. This is usually
  175.      * called by the element responsible for managing the menu.
  176.      * @param {Event} e The keydown event object.
  177.      * @return {boolean} Whether the event was handled be the menu.
  178.      */
  179.     handleKeyDown: function(e) {
  180.       var item = this.selectedItem;
  181.  
  182.       var self = this;
  183.       function selectNextAvailable(m) {
  184.         var menuItems = self.menuItems;
  185.         var len = menuItems.length;
  186.         if (!len) {
  187.           // Edge case when there are no items.
  188.           return;
  189.         }
  190.         var i = self.selectedIndex;
  191.         if (i == -1 && m == -1) {
  192.           // Edge case when needed to go the last item first.
  193.           i = 0;
  194.         }
  195.  
  196.         // "i" may be negative(-1), so modulus operation and cycle below
  197.         // wouldn't work as assumed. This trick makes startPosition positive
  198.         // without altering it's modulo.
  199.         var startPosition = (i + len) % len;
  200.  
  201.         while (true) {
  202.           i = (i + m + len) % len;
  203.  
  204.           // Check not to enter into infinite loop if all items are hidden or
  205.           // disabled.
  206.           if (i == startPosition)
  207.             break;
  208.  
  209.           item = menuItems[i];
  210.           if (item && !item.isSeparator() && !item.hidden && !item.disabled)
  211.             break;
  212.         }
  213.         if (item && !item.disabled)
  214.           self.selectedIndex = i;
  215.       }
  216.  
  217.       switch (e.keyIdentifier) {
  218.         case 'Down':
  219.           selectNextAvailable(1);
  220.           this.focusSelectedItem();
  221.           return true;
  222.         case 'Up':
  223.           selectNextAvailable(-1);
  224.           this.focusSelectedItem();
  225.           return true;
  226.         case 'Enter':
  227.         case 'U+0020': // Space
  228.           if (item) {
  229.             var activationEvent = cr.doc.createEvent('Event');
  230.             activationEvent.initEvent('activate', true, true);
  231.             activationEvent.originalEvent = e;
  232.             if (item.dispatchEvent(activationEvent)) {
  233.               if (item.command)
  234.                 item.command.execute();
  235.             }
  236.           }
  237.           return true;
  238.       }
  239.  
  240.       return false;
  241.     },
  242.  
  243.     /**
  244.      * Updates menu items command according to context.
  245.      * @param {Node=} node Node for which to actuate commands state.
  246.      */
  247.     updateCommands: function(node) {
  248.       var menuItems = this.menuItems;
  249.  
  250.       for (var i = 0, menuItem; menuItem = menuItems[i]; i++) {
  251.         if (!menuItem.isSeparator())
  252.           menuItem.updateCommand(node);
  253.       }
  254.     }
  255.   };
  256.  
  257.   function selectedIndexChanged(selectedIndex, oldSelectedIndex) {
  258.     var oldSelectedItem = this.menuItems[oldSelectedIndex];
  259.     if (oldSelectedItem) {
  260.       oldSelectedItem.selected = false;
  261.       oldSelectedItem.blur();
  262.     }
  263.     var item = this.selectedItem;
  264.     if (item)
  265.       item.selected = true;
  266.   }
  267.  
  268.   /**
  269.    * The selected menu item.
  270.    * @type {number}
  271.    */
  272.   cr.defineProperty(Menu, 'selectedIndex', cr.PropertyKind.JS,
  273.       selectedIndexChanged);
  274.  
  275.   // Export
  276.   return {
  277.     Menu: Menu
  278.   };
  279. });
  280.